/*!
 * \file ParserUDP.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief UDP行情解析器头文件
 * 
 * \details 该文件定义了ParserUDP类，是WonderTrader系统中用于接收UDP协议行情数据的核心组件：
 *          - 实现IParserApi接口，提供统一的行情解析服务
 *          - 基于UDP协议的高效行情数据传输
 *          - 支持广播和单播两种UDP通信模式
 *          - 支持多种数据类型：Tick行情、委托明细、委托队列、逐笔成交
 *          - 使用boost::asio异步网络编程框架
 *          - 提供高性能的网络数据接收和处理
 *          - 支持自动重连和错误恢复机制
 *          - 支持批量订阅和数据缓存管理
 *          - 适用于高频交易和实时行情推送场景
 * 
 * \note UDP协议具有低延迟特性，适合实时行情数据传输
 * \warning UDP是无连接协议，可能存在数据丢失，需要上层应用处理
 */
#pragma once
#include "../Includes/IParserApi.h"
#include "../Share/StdUtils.hpp"

#include <queue>

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/asio/io_service.hpp>

USING_NS_WTP;
using namespace boost::asio;

/*!
 * \class ParserUDP
 * \brief UDP行情解析器类
 * 
 * \details ParserUDP是WonderTrader系统中用于接收UDP协议行情数据的核心组件，主要功能包括：
 *          - UDP网络连接管理：负责UDP套接字的创建、绑定、重连等
 *          - 双通道数据接收：支持广播通道和服务器通道的同时接收
 *          - 多类型数据处理：支持Tick、委托明细、委托队列、逐笔成交等数据类型
 *          - 异步网络编程：基于boost::asio的高性能异步网络处理
 *          - 数据订阅管理：支持合约代码的批量订阅和动态管理
 *          - 错误处理机制：提供网络异常检测和自动重连功能
 *          - 缓冲区管理：使用boost::array提供高效的数据缓冲
 *          - 发送队列管理：支持订阅请求的队列化发送
 *          - 线程安全处理：使用strand确保线程安全的网络操作
 * 
 * \note 该类专门用于UDP协议的行情数据接收，具有低延迟特性
 * \warning UDP协议不保证数据可靠性，需要考虑数据丢失的情况
 * \see IParserApi boost::asio
 */
class ParserUDP : public IParserApi
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * 初始化ParserUDP实例，设置默认参数和网络组件
	 */
	ParserUDP();
	
	/*!
	 * \brief 析构函数
	 * 
	 * 清理资源，确保正确断开连接和释放套接字
	 */
	~ParserUDP();

	// IParserApi 接口实现
public:
	/*!
	 * \brief 初始化UDP行情解析器
	 * \param config 配置参数对象
	 * \return 是否初始化成功
	 * 
	 * \details 从配置对象中读取以下参数：
	 *          - host: UDP服务器主机地址
	 *          - bport: 广播端口号
	 *          - sport: 服务器端口号
	 *          - gpsize: 分组大小（默认1000，用于日志输出频率控制）
	 *          - 初始化服务器终端点和广播终端点
	 *          - 配置网络地址和端口绑定
	 * 
	 * \note UDP模式下需要配置两个端口：广播端口和服务器端口
	 * \warning 必须确保端口未被占用且具有访问权限
	 */
	virtual bool init(WTSVariant* config) override;

	/*!
	 * \brief 释放资源
	 * 
	 * 释放UDP行情解析器占用的所有资源
	 */
	virtual void release() override;

	/*!
	 * \brief 建立连接
	 * \return 是否连接成功
	 * 
	 * 启动UDP套接字连接，开始异步网络处理线程
	 */
	virtual bool connect() override;

	/*!
	 * \brief 断开连接
	 * \return 是否断开成功
	 * 
	 * 断开UDP连接，关闭套接字，停止网络处理
	 */
	virtual bool disconnect() override;

	/*!
	 * \brief 检查连接状态
	 * \return 是否已连接
	 * 
	 * 返回当前UDP连接状态
	 */
	virtual bool isConnected() override;

	/*!
	 * \brief 订阅行情数据
	 * \param vecSymbols 要订阅的合约代码集合
	 * 
	 * 添加合约代码到订阅列表，支持批量订阅
	 */
	virtual void subscribe(const CodeSet &vecSymbols) override;
	
	/*!
	 * \brief 退订行情数据
	 * \param vecSymbols 要退订的合约代码集合
	 * 
	 * 从订阅列表中移除合约代码
	 */
	virtual void unsubscribe(const CodeSet &vecSymbols) override;

	/*!
	 * \brief 注册行情回调接口
	 * \param listener 行情数据回调接口指针
	 * 
	 * 注册行情数据处理回调接口，用于接收处理后的行情数据
	 */
	virtual void registerSpi(IParserSpi* listener) override;


private:
	/*!
	 * \brief 处理UDP数据接收
	 * \param e boost错误代码
	 * \param bytes_transferred 接收到的字节数
	 * \param isBroad 是否为广播通道
	 * 
	 * 异步处理UDP数据接收，支持广播和服务器两种通道
	 */
	void	handle_read(const boost::system::error_code& e, std::size_t bytes_transferred, bool isBroad);
	
	/*!
	 * \brief 处理UDP数据发送完成
	 * \param e boost错误代码
	 * 
	 * 异步处理UDP数据发送完成事件
	 */
	void	handle_write(const boost::system::error_code& e);

	/*!
	 * \brief 重新连接UDP服务器
	 * \return 是否重连成功
	 * 
	 * 重新建立UDP连接，包括广播套接字和服务器套接字
	 */
	bool	reconnect();

	/*!
	 * \brief 发送订阅请求
	 * 
	 * 向UDP服务器发送合约订阅请求
	 */
	void	subscribe();

	/*!
	 * \brief 解析UDP数据缓冲区
	 * \param length 数据长度
	 * \param isBroad 是否为广播数据
	 * 
	 * 解析接收到的UDP数据包，根据类型分发到不同处理函数
	 */
	void	extract_buffer(uint32_t length, bool isBroad);

private:
	/*!
	 * \brief 处理连接成功事件
	 * 
	 * 连接成功后的回调处理
	 */
	void	doOnConnected();
	
	/*!
	 * \brief 处理连接断开事件
	 * 
	 * 连接断开后的回调处理
	 */
	void	doOnDisconnected();

	/*!
	 * \brief 执行数据发送
	 * 
	 * 从发送队列中取出数据进行发送
	 */
	void	do_send();

private:
	std::string	_hots;			///< 服务器主机地址
	int			_bport;			///< 广播端口号
	int			_sport;			///< 服务器端口号
	uint32_t	_gpsize;		///< 分组大小（日志输出频率控制）

	ip::udp::endpoint	_broad_ep;		///< 广播终端点
	ip::udp::endpoint	_server_ep;		///< 服务器终端点
	io_service			_io_service;	///< boost::asio IO服务对象

	io_service::strand	_strand;		///< boost::asio线程安全串行化对象

	ip::udp::socket*	_b_socket;		///< 广播套接字指针
	ip::udp::socket*	_s_socket;		///< 服务器套接字指针

	boost::array<char, 1024> _b_buffer;	///< 广播数据接收缓冲区
	boost::array<char, 1024> _s_buffer;	///< 服务器数据接收缓冲区

	IParserSpi*		_sink;				///< 行情数据回调接口指针
	bool			_stopped;			///< 停止标志
	bool			_connecting;		///< 连接中标志

	CodeSet			_set_subs;			///< 订阅合约代码集合

	StdThreadPtr	_thrd_parser;		///< 网络处理线程指针

	std::queue<std::string>	_send_queue;///< 发送数据队列
};

